package com.google.code.mochaccino.framework.activemq;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Provider;
import org.apache.activemq.broker.BrokerPlugin;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.DestinationFactory;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.store.PersistenceAdapter;
import org.apache.activemq.usage.MemoryUsage;
import org.apache.activemq.usage.SystemUsage;
import org.apache.activemq.util.IOExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** POJO Provider for a Broker Service. */
public class BrokerServiceProvider implements Provider<BrokerService> {
	private BrokerPlugin[]     plugins            = new BrokerPlugin[0];
	private DestinationFactory destinationFactory = null;
	private File               home               = new File( "activemq" );
	private IOExceptionHandler handler            = new IOExceptionHandler() {
		private Logger logger = LoggerFactory.getLogger( getClass() );

		@Override
		public void handle( IOException e ) {
			logger.error( e.getMessage(), e );
		}

		@Override
		public void setBrokerService( BrokerService brokerService ) {
		}
	};

	private PersistenceAdapter persistenceAdapter                    = null;
	private PolicyMap          policyMap                             = null;
	private String[]           connectorURIs                         = new String[0];
	private String             name                                  = "broker";
	private SystemUsage        consumerSystemUsage                   = usage( 10, 1024 * 1024 * 1024 );
	private SystemUsage        producerSystemUsage                   = usage( 10, 1024 * 1024 * 1024 );
	private SystemUsage        systemUsage                           = usage( 10, 1024 * 1024 * 1024 );
	private boolean            advisorySupport                       = false;
	private boolean            cacheTempDestinations                 = false;
	private boolean            dedicatedTaskRunner                   = true;
	private boolean            deletePersistentMessagesOnStartup     = false;
	private boolean            enableStatistics                      = true;
	private boolean            keepDurableSubsActive                 = false;
	private boolean            monitorConnectionSplits               = false;
	private boolean            persistent                            = false;
	private boolean            populateJMSXUserID                    = false;
	private boolean            schedulerSupport                      = true;
	private boolean            splitSystemUsageForProducersConsumers = true;
	private boolean            supportFailOver                       = false;
	private boolean            systemExitOnShutdown                  = false;
	private boolean            useJmx                                = true;
	private boolean            useLoggingForShutdownErrors           = true;
	private boolean            useShutdownHook                       = true;
	private boolean            useTempMirroredQueues                 = false;
	private boolean            useVirtualTopics                      = true;

	/** Constructor */
	public BrokerServiceProvider( String name ) {
		this.name = name;
	}

	/** Constructor */
	public BrokerServiceProvider( int port, String name ) {
		this.name = name;
		this.connectorURIs = new String[] { "tcp://localhost:" + port };
	}

	/** Create a system usage */
	public static final SystemUsage usage( int nbThread, long memoryUsageInBytes ) {
		MemoryUsage memoryUsage = new MemoryUsage();
		memoryUsage.setUsage( memoryUsageInBytes );

		SystemUsage usage = new SystemUsage();
		usage.setMemoryUsage( memoryUsage );
		usage.setExecutor( (ThreadPoolExecutor) Executors.newFixedThreadPool( nbThread ) );
		return usage;
	}

	@Override
	public BrokerService get() {
		try {
			BrokerService service = new BrokerService();
			service.setAdvisorySupport( advisorySupport );
			service.setBrokerId( name );
			service.setBrokerName( name );
			service.setCacheTempDestinations( cacheTempDestinations );
			service.setConsumerSystemUsage( consumerSystemUsage );
			service.setDataDirectoryFile( new File( home, "data" ) );
			service.setDedicatedTaskRunner( dedicatedTaskRunner );
			service.setDeleteAllMessagesOnStartup( deletePersistentMessagesOnStartup );
			service.setDestinationFactory( destinationFactory );
			service.setDestinationPolicy( policyMap );
			service.setEnableStatistics( enableStatistics );
			service.setIoExceptionHandler( handler );
			service.setKeepDurableSubsActive( keepDurableSubsActive );
			service.setMonitorConnectionSplits( monitorConnectionSplits );
			service.setPersistenceAdapter( persistenceAdapter );
			service.setPersistent( persistent );
			service.setPlugins( plugins );
			service.setPopulateJMSXUserID( populateJMSXUserID );
			service.setProducerSystemUsage( producerSystemUsage );
			service.setSchedulerDirectoryFile( new File( home, "sched" ) );
			service.setSchedulerSupport( schedulerSupport );
			service.setSplitSystemUsageForProducersConsumers( splitSystemUsageForProducersConsumers );
			service.setSupportFailOver( supportFailOver );
			service.setSystemExitOnShutdown( systemExitOnShutdown );
			service.setSystemUsage( systemUsage );
			service.setTmpDataDirectory( new File( home, "tmp" ) );
			service.setTransportConnectorURIs( connectorURIs );
			service.setUseJmx( useJmx );
			service.setUseLoggingForShutdownErrors( useLoggingForShutdownErrors );
			service.setUseShutdownHook( useShutdownHook );
			service.setUseTempMirroredQueues( useTempMirroredQueues );
			service.setUseVirtualTopics( useVirtualTopics );
			return service;
		} catch ( Exception e ) {
			throw new RuntimeException( e );
		}
	}

	public void setAdvisorySupport( boolean advisorySupport ) {
		this.advisorySupport = advisorySupport;
	}

	public void setCacheTempDestinations( boolean cacheTempDestinations ) {
		this.cacheTempDestinations = cacheTempDestinations;
	}

	public void setConnectorURIs( String[] connectorURIs ) {
		this.connectorURIs = Arrays.copyOf(connectorURIs, connectorURIs.length);
	}

	public void setConsumerSystemUsage( SystemUsage consumerSystemUsage ) {
		this.consumerSystemUsage = consumerSystemUsage;
	}

	public void setDedicatedTaskRunner( boolean dedicatedTaskRunner ) {
		this.dedicatedTaskRunner = dedicatedTaskRunner;
	}

	public void setDeletePersistentMessagesOnStartup( boolean deletePersistentMessagesOnStartup ) {
		this.deletePersistentMessagesOnStartup = deletePersistentMessagesOnStartup;
	}

	public void setDestinationFactory( DestinationFactory destinationFactory ) {
		this.destinationFactory = destinationFactory;
	}

	public void setEnableStatistics( boolean enableStatistics ) {
		this.enableStatistics = enableStatistics;
	}

	public void setHandler( IOExceptionHandler handler ) {
		this.handler = handler;
	}

	public void setHome( File home ) {
		this.home = home;
	}

	public void setKeepDurableSubsActive( boolean keepDurableSubsActive ) {
		this.keepDurableSubsActive = keepDurableSubsActive;
	}

	public void setMonitorConnectionSplits( boolean monitorConnectionSplits ) {
		this.monitorConnectionSplits = monitorConnectionSplits;
	}

	public void setName( String name ) {
		this.name = name;
	}

	public void setPersistenceAdapter( PersistenceAdapter persistenceAdapter ) {
		this.persistenceAdapter = persistenceAdapter;
	}

	public void setPersistent( boolean persistent ) {
		this.persistent = persistent;
	}

	public void setPlugins( BrokerPlugin[] plugins ) {
		this.plugins = Arrays.copyOf( plugins, plugins.length );
	}

	public void setPolicyMap( PolicyMap policyMap ) {
		this.policyMap = policyMap;
	}

	public void setPopulateJMSXUserID( boolean populateJMSXUserID ) {
		this.populateJMSXUserID = populateJMSXUserID;
	}

	public void setProducerSystemUsage( SystemUsage producerSystemUsage ) {
		this.producerSystemUsage = producerSystemUsage;
	}

	public void setSchedulerSupport( boolean schedulerSupport ) {
		this.schedulerSupport = schedulerSupport;
	}

	public void setSplitSystemUsageForProducersConsumers( boolean splitSystemUsageForProducersConsumers ) {
		this.splitSystemUsageForProducersConsumers = splitSystemUsageForProducersConsumers;
	}

	public void setSupportFailOver( boolean supportFailOver ) {
		this.supportFailOver = supportFailOver;
	}

	public void setSystemExitOnShutdown( boolean systemExitOnShutdown ) {
		this.systemExitOnShutdown = systemExitOnShutdown;
	}

	public void setSystemUsage( SystemUsage systemUsage ) {
		this.systemUsage = systemUsage;
	}

	public void setUseJmx( boolean useJmx ) {
		this.useJmx = useJmx;
	}

	public void setUseLoggingForShutdownErrors( boolean useLoggingForShutdownErrors ) {
		this.useLoggingForShutdownErrors = useLoggingForShutdownErrors;
	}

	public void setUseShutdownHook( boolean useShutdownHook ) {
		this.useShutdownHook = useShutdownHook;
	}

	public void setUseTempMirroredQueues( boolean useTempMirroredQueues ) {
		this.useTempMirroredQueues = useTempMirroredQueues;
	}

	public void setUseVirtualTopics( boolean useVirtualTopics ) {
		this.useVirtualTopics = useVirtualTopics;
	}
}
